package com.mxfcode.bbs_common.util;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.*;
import java.util.stream.Collectors;

public class StringUtils {


    /*转为下划线*/
    public static String underscoreName(String name) {
        StringBuilder result = new StringBuilder();
        if (name != null && name.length() > 0) {
            // 将第一个字符处理成小写
            result.append(name.substring(0, 1).toLowerCase());
            // 循环处理其余字符
            for (int i = 1; i < name.length(); i++) {
                String s = name.substring(i, i + 1);

                if(s.equals("_")){
                    continue;
                }
                // 在大写字母前添加下划线
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                    result.append("_");
                }
                // 其他字符直接转成小写
                result.append(s.toLowerCase());
            }
        }
        return result.toString();
    }

    /*转为驼峰MAP*/
    public static Map<String,Object> underscoreName(Map<String,Object> map) {
        Map<String, Object> newMap = new HashMap<>();
        for (Map.Entry<String,Object> entry : map.entrySet()) {
            newMap.put(underscoreName(entry.getKey()),entry.getValue());
        }
        return newMap;
    }

    /**
     * 对字符串md5加密(小写+字母)
     *
     * @param str 传入要加密的字符串
     * @return  MD5加密后的字符串
     */
    public static String MD5Lowercase(String str) {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes());
            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 对字符串md5加密(大写+数字)
     *
     * @param s 传入要加密的字符串
     * @return  MD5加密后的字符串
     */

    public static String MD5Upcase(String s) {
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

        try {
            byte[] btInput = s.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 处理的最大数字达千万亿位 精确到分
     * @return
     */
    public static String digitUppercase(String num) throws Exception{
        String fraction[] = {"角", "分"};
        String digit[] = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
        /**
         *      仟        佰        拾         ' '
         ' '    $4        $3        $2         $1
         万     $8        $7        $6         $5
         亿     $12       $11       $10        $9
         */
        String unit1[] = {"", "拾", "佰", "仟"};//把钱数分成段,每四个一段,实际上得到的是一个二维数组
        String unit2[] = {"元", "万", "亿","万亿"}; //把钱数分成段,每四个一段,实际上得到的是一个二维数组
        BigDecimal bigDecimal =  new BigDecimal(num);
        bigDecimal=bigDecimal.multiply(new BigDecimal(100));
//        Double bigDecimal = new Double(name*100);     存在精度问题 eg：145296.8
        String strVal = String.valueOf(bigDecimal.toBigInteger());
        String head = strVal.substring(0,strVal.length()-2);         //整数部分
        String end = strVal.substring(strVal.length()-2);              //小数部分
        String endMoney="";
        String headMoney = "";
        if("00".equals(end)){
            endMoney = "整";
        }else{
            if(!end.substring(0,1).equals("0")){
                endMoney+=digit[Integer.valueOf(end.substring(0,1))]+"角";
            }else if(end.substring(0,1).equals("0") && !end.substring(1,2).equals("0")){
                endMoney+= "零";
            }
            if(!end.substring(1,2).equals("0")){
                endMoney+=digit[Integer.valueOf(end.substring(1,2))]+"分";
            }
        }
        char[] chars = head.toCharArray();
        Map<String,Boolean> map = new HashMap<String,Boolean>();//段位置是否已出现zero
        boolean zeroKeepFlag = false;//0连续出现标志
        int vidxtemp = 0;
        for(int i=0;i<chars.length;i++){
            int idx = (chars.length-1-i)%4;//段内位置  unit1
            int vidx = (chars.length-1-i)/4;//段位置 unit2
            String s = digit[Integer.valueOf(String.valueOf(chars[i]))];
            if(!"零".equals(s)){
                headMoney += s +unit1[idx]+unit2[vidx];
                zeroKeepFlag = false;
            }else if(i==chars.length-1 || map.get("zero"+vidx)!=null){
                headMoney += "" ;
            }else{
                headMoney += s;
                zeroKeepFlag = true;
                map.put("zero"+vidx,true);//该段位已经出现0；
            }
            if(vidxtemp!=vidx || i==chars.length-1){
                headMoney = headMoney.replaceAll(unit2[vidx],"");
                headMoney+=unit2[vidx];
            }
            if(zeroKeepFlag && (chars.length-1-i)%4==0){
                headMoney = headMoney.replaceAll("零","");
            }
        }
        return headMoney+endMoney;
    }

    //判断一个String是否为null,""," "
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    public static boolean isBlank(String str) {
        int strLen;
        if (str != null && (strLen = str.length()) != 0) {
            for(int i = 0; i < strLen; ++i) {
                if (!Character.isWhitespace(str.charAt(i))) {
                    return false;
                }
            }
            return true;
        } else {
            return true;
        }
    }
    //判断Str中char的位置
    public static int lastIndexOf(String str, char searchChar) {
        return isEmpty(str) ? -1 : str.lastIndexOf(searchChar);
    }
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }
    //判断String是否都为null或者值相等
    public static boolean equals(String str1, String str2) {
        return str1 == null ? str2 == null : str1.equals(str2);
    }
    //判断第一次出现子串的位置,不存在的话则返回-1
    public static int indexOf(String str, String searchStr) {
        return str != null && searchStr != null ? str.indexOf(searchStr) : -1;
    }
    //判断最后一次子串出现的位置，不存在的话则返回-1
    public static int lastIndexOf(String str, String searchStr) {
        return str != null && searchStr != null ? str.lastIndexOf(searchStr) : -1;
    }
    //截取字符串指定位置后面的子串
    public static String substring(String str, int start) {
        if (str == null) {
            return null;
        } else {
            if (start < 0) {
                start += str.length();
            }

            if (start < 0) {
                start = 0;
            }

            return start > str.length() ? "" : str.substring(start);
        }
    }
    //截取字符串指定位置开始和结束的子串
    public static String substring(String str, int start, int end) {
        if (str == null) {
            return null;
        } else {
            if (end < 0) {
                end += str.length();
            }
            if (start < 0) {
                start += str.length();
            }
            if (end > str.length()) {
                end = str.length();
            }
            if (start > end) {
                return "";
            } else {
                if (start < 0) {
                    start = 0;
                }
                if (end < 0) {
                    end = 0;
                }
                return str.substring(start, end);
            }
        }
    }
    //以list的方式返回List<Map<String,Object>>类型指定key下面的值,去掉"",和null的情况
    public static List<String> getListItemValue(List<Map<String,Object>> list, String key){
        List<String> resultList = list.stream()
                .filter(map -> map.get(key) != null && !"".equals(map.get(key)))
                .map(item -> item.get(key).toString()).collect(Collectors.toList());
        return resultList;
    }
    //以set的方式返回List<Map<String,Object>>类型指定key下面的值，去掉"",和null的情况
    public static Set<String> getSetItemValue(List<Map<String,Object>> list, String key){
        Set<String> resultSet = list.stream()
                    .filter(map -> map.get(key) != null && !"".equals(map.get(key)))
                    .map(map -> map.get(key).toString()).collect(Collectors.toSet());
        return resultSet;
    }
    public static String getStreamValues(List<Map<String,Object>> list,String key){
        StringBuffer resultSB = new StringBuffer();
        list.stream().filter(map -> map.get(key) != null && !"".equals(map.get(key)))
                .collect(Collectors.toSet())
                .forEach(map -> {
                    resultSB.append(map.get(key) + ",");
                });
        return resultSB.length() > 0 ? resultSB.deleteCharAt(resultSB.length()-1).toString() : "没有符合条件的元素" ;
    }
    public static void main(String[] args) {
        String str1 = null;
        String str2 = "";
        String str3 = " ";
//        System.out.println(StringUtils.isNotBlank(str1));//false
//        System.out.println(StringUtils.isNotBlank(str2));//false
//        System.out.println(StringUtils.isNotBlank(str2));//false

        String str4 = "城市粗犷我粗业务财务从路分隔符";
//        System.out.println(StringUtils.lastIndexOf(str4,'路'));//11
        String str5 = "业务";
//        System.out.println(StringUtils.indexOf(str4,str5));
//        System.out.println(StringUtils.lastIndexOf(str4,str5));
//        System.out.println(StringUtils.substring(str4,5));
//        System.out.println(StringUtils.substring(str4,5,str4.length()-1));
        Map<String,Object> o1 = new HashMap<>();
        o1.put("id","id");
        o1.put("name","name1");
        Map<String,Object> o2 = new HashMap<>();
        o2.put("id","");
        o2.put("name","name2");
        Map<String,Object> o3 = new HashMap<>();
        o3.put("id",null);
        o3.put("name","name3");
        Map<String,Object> o4 = new HashMap<>();
        o4.put("id","id");
        o4.put("name","name1");
        List<Map<String,Object>> list = new ArrayList<>();
        String nameStr = StringUtils.getStreamValues(list, "id");
//        System.out.println(nameStr);
        list.add(o1);
        list.add(o2);
        list.add(o3);
        list.add(o4);
        List<String> idsList = StringUtils.getListItemValue(list, "id");
//        System.out.println(idsList);
        Set<String> idsSet = StringUtils.getSetItemValue(list,"id");
//        System.out.println(idsSet);
//        String nameStr = StringUtils.getStreamValues(list, "id");
//        System.out.println(nameStr);
    }
}